import Player from "../../player/Player";
import GameManager from "../../manager/GameManager";
import NodePoolManager from "../../manager/NodePoolManager";
import MinerHome from "../../funcObj/interface/MinerHome";
import DestructibleFacility from "../DestructibleFacility";
import DomainMaker from "../../funcObj/interface/DomainMaker";
import PlayerManager from "../../manager/PlayerManager";
import { Killer } from "../../funcObj/interface/HealthPoint";
import Miner from "../../flyer/Other/Miner";
import { GamePropType } from "../../info/GameEnum";
import ScoutReserve from "../../prop/ScoutReserve";
import FlareReserve from "../../prop/FlareReserve";
import { Location, MapLength } from "../../info/Predefine";
import MusicManager from "../../../MusicManager";
import { Global } from "../../info/Global";

const { ccclass, property } = cc._decorator;

@ccclass
export default class MainHome extends DestructibleFacility implements MinerHome, DomainMaker {

    @property([cc.SpriteFrame])
    allMainSprites: cc.SpriteFrame[] = [];

    @property(cc.Node)
    minerAddTip: cc.Node = null;

    @property(cc.Node)
    upgradeTip: cc.Node = null;

    minerArr: Miner[];

    myDomain: Location[];

    init(player: Player): void {
        this.myDomain = [];
        super.init(player);
        let buildAniNode = this.node.getChildByName("mainBuilding");
        let buildAni = buildAniNode.getComponent(cc.Animation);
        let baseNode = this.node.getChildByName("base");
        let flagAni = baseNode.getComponentInChildren(cc.Animation);
        let buildAniClips = buildAni.getClips();
        let flagAniClips = flagAni.getClips();
        buildAni.play(buildAniClips[this.player.playerId].name);
        buildAni.on(cc.Animation.EventType.FINISHED, () => {
            buildAniNode.destroy();
            baseNode.active = true;
            baseNode.getComponent(cc.Sprite).spriteFrame = this.allMainSprites[this.player.playerId];
            flagAni.play(flagAniClips[this.player.playerId].name);
        })

        this.resetViewAndDomain();

        //一个矿工
        this.minerArr = [];

        this.addMiner();
        if (this.player.props[GamePropType.矿工储备]) {
            this.addMiner();
        }

        this.player.diamond += 50;

        if (player == PlayerManager.instance.controllerPlayer) {
            this.onChangeDiamond(this.player.diamond);
            //监听
            this.player.node.on(Player.EventType.更新晶石, this.onChangeDiamond, this);
        } else {
            this.upgradeTip.active = false;
            this.minerAddTip.active = false;
        }
        MusicManager.instance.play(MusicManager.instance.build_build, this.node);
    }

    /**
     * 添加道具
     */
    protected addProp(): void {
        super.addProp();
        if (this.player.props[GamePropType.侦察机储备]) {
            let sr = NodePoolManager.instance.obtain(NodePoolManager.instance.scoutReserve);
            sr.parent = this.node;
            sr.getComponent(ScoutReserve).init(this.player, this);
        }

        if (this.player.props[GamePropType.照明弹储备]) {
            let fr = NodePoolManager.instance.obtain(NodePoolManager.instance.flareReserve);
            fr.parent = this.node;
            fr.getComponent(FlareReserve).init(this.player, this);
        }
    }

    die(killer: Killer): void {
        super.die(killer);
        //回收矿工
        this.minerArr.forEach(item => NodePoolManager.instance.recycle(item.node))
        this.minerArr = null;
        //玩家失去领地
        this.player.loseDomain(this.myDomain);
        // 删除玩家 ，提示玩家被消灭
        this.player.die(killer);
        this.node.destroy();
    }

    /**
     * 当矿石数量更新时,判断是否可以招募矿工，是否可以升级基地
     */
    onChangeDiamond(diamond: number) {
        //提示
        let price = this.player.minerPrice;
        this.minerAddTip.active = diamond >= price.diamond;
        price = this.facilityInfo.每等级升级要求[this.player.mainHomeLevel];
        this.upgradeTip.active = price && diamond >= price.diamond;
    }

    /**
     * 获得矿石数量
     * @param carryCount 矿工携带的数量
     */
    public addMineCount(carryCount: number) {
        this.player.diamond += carryCount;
        //播放获得矿石的动画
        this.player == PlayerManager.instance.controllerPlayer && GameManager.instance.showResourceTips(1, carryCount, this.node.position);
    }

    levelUp(): void {
        super.levelUp();
        this.resetViewAndDomain();
    }

    /**
     * 增加地盘和视野
     */
    resetViewAndDomain() {
        let levelMap = Global.MainHomeLevelDomain[this.level];
        let radius = levelMap.length / 2;
        let leftDown = this.locations[0];
        this.locations.forEach(item => {
            if (item.locationX < leftDown.locationX || item.locationY > leftDown.locationY) {
                leftDown = item;
            }
        })

        let minX = leftDown.locationX - radius + 1;
        let maxX = leftDown.locationX + radius;
        let minY = leftDown.locationY - radius;
        let maxY = leftDown.locationY + radius - 1;
        let tempLocations: Location[] = [];
        for (let y = minY, pointY = 0; y <= maxY; y++, pointY++) {
            for (let x = minX, pointX = 0; x <= maxX; x++, pointX++) {
                if (x >= 0 && x < MapLength && y >= 0 && y < MapLength) {
                    if (levelMap[pointY][pointX] == 1) {
                        tempLocations.push({ locationX: x, locationY: y });
                    }
                }
            }
        }

        let oldDomain = this.myDomain;
        this.myDomain = tempLocations;

        let newDomain = tempLocations.filter(newlocation => !oldDomain.find(oldLocation => oldLocation.locationX == newlocation.locationX && oldLocation.locationY == newlocation.locationY));
        this.player.onGetNewDomain(newDomain);
    }

    /**
     * 添加矿工
     */
    addMiner(): void {
        let price = this.player.minerPrice;
        this.player.diamond -= price.diamond;
        this.player.oil -= price.oil;
        let miner = NodePoolManager.instance.obtain(NodePoolManager.instance.minerPrefab);
        miner.position = this.node.position;
        miner.parent = GameManager.instance.minerParent;
        let minerComp = miner.getComponent(Miner)
        minerComp.init(this);
        this.minerArr.push(minerComp);
    }

}
